import logging
from datetime import datetime, timedelta
from typing import cast
from django.db.models import QuerySet, Q
import requests

from api.models import Project
from django.contrib.auth import get_user_model
from django.db.models import Count, Q
from rest_framework import status, permissions, generics
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken

from .serializers import (
    UserSerializer, UserRegistrationSerializer, LoginSerializer,
    ChangePasswordSerializer, UserManagementSerializer
)

User = get_user_model()
logger = logging.getLogger('api')

# 用户注册的相关API


class RegisterView(APIView):
    """用户注册"""
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        logger.info(f"📝 注册请求数据: {request.data}")

        # 处理字段名映射 - 支持前端发送的 confirmPassword
        data = request.data.copy()
        if 'confirmPassword' in data and 'password_confirm' not in data:
            data['confirmPassword'] = data['confirmPassword']

        serializer = UserRegistrationSerializer(data=data)
        if serializer.is_valid():
            user = serializer.save()
            refresh = RefreshToken.for_user(user)
            logger.info(f"✅ 新用户注册成功: {user.username} (ID: {user.id})")

            return Response({
                'success': True,
                'message': '注册成功',
                'data': {
                    'user': UserSerializer(user).data,
                    'token': str(refresh.access_token),
                    'refresh': str(refresh)
                }
            }, status=status.HTTP_201_CREATED)

        logger.error(f"❌ 注册失败，验证错误: {serializer.errors}")
        return Response({
            'success': False,
            'message': '注册失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


# 登录的相关API
class LoginView(APIView):
    """用户登录"""
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        logger.info(f"📝 登录请求数据: {request.data}")

        serializer: LoginSerializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']

            # 更新最后登录IP
            user.last_login_ip = self.get_client_ip(request)
            user.save(update_fields=['last_login_ip'])

            refresh = RefreshToken.for_user(user)
            logger.info(
                f"✅ 用户登录成功: {user.username} (ID: {user.id}) - 管理员: {user.is_admin or user.is_superuser}")

            return Response({
                'success': True,

                'message': '登录成功',
                'data': {
                    'user': UserSerializer(user).data,
                    'token': str(refresh.access_token),
                    'refresh': str(refresh)
                }
            })

        logger.error(f"❌ 登录失败，验证错误: {serializer.errors}")
        return Response({
            'success': False,
            'message': '登录失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


# 第三方登录的类，主要是用于给make平台登录 返回的token时长为永久，应该提醒用户
class ThirdPartyLoginView(APIView):
    """第三方登录 - 永久token"""
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        logger.info(f"📝 第三方登录请求数据: {request.data}")
        # 首先校验订单编号是否有效 有效再去校验用户名和密码
        order_token = request.data.get('order_token')
        if not order_token:
            logger.error("❌ 第三方登录失败，缺少订单编号")
            return Response({
                'success': False,
                'message': '第三方登录失败，缺少订单编号'
            }, status=status.HTTP_401_UNAUTHORIZED)

        # 如果订单校验失败
        is_valid, order_value = self.validate_order(order_token)
        if not is_valid:
            logger.error(
                f"❌ 第三方登录失败，订单验证失败\n 如果您还未购买，欢迎前往 https://www.ricoxueai.cn 下单！")
            return Response({
                'success': False,
                'message': f'第三方登录失败，订单验证失败\n 如果您还未购买，欢迎前往 https://www.ricoxueai.cn 下单！'
            }, status=status.HTTP_401_UNAUTHORIZED)

        # 如果订单校验成功，继续进行用户名和密码的验证
        serializer: LoginSerializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']

            # 更新最后登录IP
            user.last_login_ip = self.get_client_ip(request)
            user.save(update_fields=['last_login_ip'])

            # 创建永久访问令牌
            refresh = RefreshToken.for_user(user)
            access_token = refresh.access_token

            # 设置永久有效期（设置为一个很大的值，比如100年）
            access_token.set_exp(lifetime=timedelta(days=36500))  # 100年

            logger.info(
                f"✅ 第三方用户登录成功: {user.username} (ID: {user.id}) - 管理员: {user.is_admin or user.is_superuser}")

            return Response({
                'success': True,
                'message': '第三方登录成功',
                'data': {
                    'user': UserSerializer(user).data,
                    'token': str(access_token),  # 永久有效的访问令牌
                    'token_type': 'permanent',
                    'expires_in': None,  # 永不过期
                    'note': '此令牌为永久有效，请妥善保管'
                }
            }, status=status.HTTP_200_OK)

        logger.error(f"❌ 第三方登录失败，验证用户名或者密码时错误: {serializer.errors}")
        return Response({
            'success': False,
            'message': '第三方登录失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    # 校验订单号是否合法
    def validate_order(self, order_token):
        try:
            response = requests.get(
                'https://hook.us2.make.com/a1c31elkblhoprqwh639a81ugpf9n33g',
                params={'token': order_token}
            )
            res = response.json()
            value = res.get('expires')

            if value is not None:
                logger.info("订单验证成功，订单编号: %s", value)
                return True, value

            return False, "订单验证失败"

        except Exception as e:
            error_msg = f"订单验证过程中出现错误: {str(e)}"
            logger.error(error_msg)
            return False, error_msg

    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


# 登出的相关API
class LogoutView(APIView):
    """用户登出"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        try:
            refresh_token = request.data.get('refresh')
            if refresh_token:
                token = RefreshToken(refresh_token)
                token.blacklist()

            return Response({
                'success': True,
                'message': '登出成功'
            })
        except Exception as e:
            return Response({
                'success': False,
                'message': f'登出失败: {str(e)}'
            }, status=status.HTTP_400_BAD_REQUEST)


# 用户资料管理的相关API
class UserProfileView(APIView):
    """用户资料管理"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        """获取当前用户信息"""
        user_data = UserSerializer(request.user).data
        logger.info(
            f"📝 用户 {request.user.username} 获取资料，权限: {user_data.get('permissions', {})}")

        return Response({
            'success': True,
            'data': user_data
        })

    def put(self, request):
        """更新用户资料"""
        serializer = UserSerializer(
            request.user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            logger.info(
                f"✅ 用户资料更新成功: {request.user.username} (ID: {request.user.id})")
            return Response({
                'success': True,
                'message': '资料更新成功',
                'data': serializer.data
            })

        return Response({
            'success': False,
            'message': '更新失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class ChangePasswordView(APIView):
    """修改密码"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        serializer = ChangePasswordSerializer(
            data=request.data, context={'request': request})
        if serializer.is_valid():
            user = request.user
            user.set_password(serializer.validated_data['new_password'])
            user.save()
            logger.info(f"✅ 用户密码修改成功: {user.username} (ID: {user.id})")

            return Response({
                'success': True,
                'message': '密码修改成功'
            })

        return Response({
            'success': False,
            'message': '密码修改失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class UserListView(generics.ListCreateAPIView):
    """用户列表管理（管理员功能）"""
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = UserSerializer
    queryset = User.objects.all()

    def get_serializer_class(self) -> type:
        # POST请求使用管理序列化器，GET请求使用普通序列化器
        if self.request.method == 'POST':
            from .serializers import UserManagementSerializer
            return UserManagementSerializer
        return UserSerializer

    def get_queryset(self) -> QuerySet:
        # 只有管理员可以看到所有用户，普通用户只能看到自己
        if self.request.user.is_admin or self.request.user.is_superuser:
            queryset = User.objects.all().order_by('-created_at')
        else:
            queryset = User.objects.filter(id=self.request.user.id)

        # 添加搜索功能
        search = self.request.query_params.get('search', '').strip()
        if search:
            # 支持按用户名、邮箱、昵称进行模糊搜索
            queryset = queryset.filter(
                Q(username__icontains=search) |
                Q(email__icontains=search) |
                Q(nickname__icontains=search)
            )

        # 添加状态筛选
        is_active = self.request.query_params.get('is_active')
        if is_active is not None:
            is_active_bool = is_active.lower() in ['true', '1', 'yes', 'on']
            queryset = queryset.filter(is_active=is_active_bool)

        # 添加管理员状态筛选
        is_admin = self.request.query_params.get('is_admin')
        if is_admin is not None:
            is_admin_bool = is_admin.lower() in ['true', '1', 'yes', 'on']
            queryset = queryset.filter(is_admin=is_admin_bool)

        # 添加超级用户状态筛选
        is_superuser = self.request.query_params.get('is_superuser')
        if is_superuser is not None:
            is_superuser_bool = is_superuser.lower() in [
                'true', '1', 'yes', 'on']
            queryset = queryset.filter(is_superuser=is_superuser_bool)

        # 添加日期范围筛选
        date_from = self.request.query_params.get('date_from')
        date_to = self.request.query_params.get('date_to')
        if date_from:
            try:
                from_date = datetime.strptime(date_from, '%Y-%m-%d').date()
                queryset = queryset.filter(created_at__date__gte=from_date)
            except ValueError:
                pass  # 忽略无效日期格式

        if date_to:
            try:
                to_date = datetime.strptime(date_to, '%Y-%m-%d').date()
                queryset = queryset.filter(created_at__date__lte=to_date)
            except ValueError:
                pass  # 忽略无效日期格式

        # 添加排序功能
        ordering = self.request.query_params.get('ordering', '-created_at')
        valid_orderings = [
            'id', '-id', 'username', '-username', 'email', '-email',
            'nickname', '-nickname', 'created_at', '-created_at',
            'last_login', '-last_login', 'is_active', '-is_active',
            'is_admin', '-is_admin', 'is_superuser', '-is_superuser'
        ]
        if ordering in valid_orderings:
            queryset = queryset.order_by(ordering)
        else:
            queryset = queryset.order_by('-created_at')

        return queryset

    def get_permissions(self):
        # 获取用户列表需要登录，创建用户需要管理员权限
        if self.request.method == 'POST':
            return [permissions.IsAuthenticated()]
        return super().get_permissions()

    def list(self, request, *args, **kwargs):
        """重写列表方法，返回格式化的用户列表"""
        queryset = self.get_queryset()

        # 分页处理
        page_size = int(self.request.query_params.get('page_size', 20))
        page = int(self.request.query_params.get('page', 1))

        # 限制每页最大数量
        page_size = min(page_size, 100)

        # 计算偏移量
        offset = (page - 1) * page_size
        total_count = queryset.count()

        # 应用分页
        paginated_queryset = queryset[offset:offset + page_size]

        serializer = self.get_serializer(paginated_queryset, many=True)

        # 获取搜索参数用于日志记录
        search_params = {
            'search': self.request.query_params.get('search', ''),
            'is_active': self.request.query_params.get('is_active'),
            'is_admin': self.request.query_params.get('is_admin'),
            'ordering': self.request.query_params.get('ordering', '-created_at'),
            'page': page,
            'page_size': page_size
        }

        logger.info(
            f"📋 用户 {request.user.username} 获取用户列表，总数: {total_count}，"
            f"当前页: {page}，每页: {page_size}，搜索条件: {search_params}")

        return Response({
            'success': True,
            'data': serializer.data,
            'pagination': {
                'total': total_count,
                'page': page,
                'page_size': page_size,
                'total_pages': (total_count + page_size - 1) // page_size,
                'has_next': offset + page_size < total_count,
                'has_previous': page > 1
            },
            'filters': {
                'search': self.request.query_params.get('search', ''),
                'is_active': self.request.query_params.get('is_active'),
                'is_admin': self.request.query_params.get('is_admin'),
                'is_superuser': self.request.query_params.get('is_superuser'),
                'date_from': self.request.query_params.get('date_from'),
                'date_to': self.request.query_params.get('date_to'),
                'ordering': self.request.query_params.get('ordering', '-created_at')
            }
        })

    def create(self, request, *args, **kwargs):
        """重写创建方法，返回格式化响应"""
        # 检查用户权限
        if not (request.user.is_admin or request.user.is_superuser):
            return Response({
                'success': False,
                'message': '权限不足，只有管理员可以创建用户'
            }, status=status.HTTP_403_FORBIDDEN)

        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            logger.info(
                f"✅ 管理员 {request.user.username} 创建用户成功: {user.username} (ID: {user.id})")

            return Response({
                'success': True,
                'message': '用户创建成功',
                'data': UserSerializer(user).data
            }, status=status.HTTP_201_CREATED)

        logger.error(f"❌ 用户创建失败，验证错误: {serializer.errors}")
        return Response({
            'success': False,
            'message': '用户创建失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
    """用户详情管理"""
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = User.objects.all()

    def get_queryset(self) -> QuerySet:
        # 只有管理员可以管理所有用户，普通用户只能管理自己
        if self.request.user.is_admin or self.request.user.is_superuser:
            return User.objects.all()
        return User.objects.filter(id=self.request.user.id)

    def get_serializer_class(self) -> type:
        # 更新操作使用管理序列化器
        if self.request.method in ['PUT', 'PATCH']:
            from .serializers import UserManagementSerializer
            return UserManagementSerializer
        return UserSerializer

    def retrieve(self, request, *args, **kwargs):
        """重写详情方法，返回格式化的用户详情"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)

        logger.info(
            f"📋 用户 {request.user.username} 获取用户详情: {instance.username}")

        return Response({
            'success': True,
            'data': serializer.data
        })

    def update(self, request, *args, **kwargs):
        """重写更新方法，返回格式化响应"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()

        # 检查权限：管理员可以修改任何用户，普通用户只能修改自己
        if not (request.user.is_admin or request.user.is_superuser or instance.id == request.user.id):
            return Response({
                'success': False,
                'message': '权限不足，无法修改该用户信息'
            }, status=status.HTTP_403_FORBIDDEN)

        serializer = self.get_serializer(
            instance, data=request.data, partial=partial)

        if serializer.is_valid():
            user = serializer.save()
            logger.info(
                f"✅ 用户信息更新成功: {user.username} (ID: {user.id}) by {request.user.username}")

            return Response({
                'success': True,
                'message': '用户信息更新成功',
                'data': UserSerializer(user).data
            })

        return Response({
            'success': False,
            'message': '用户信息更新失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def destroy(self, request, *args, **kwargs):
        """重写删除方法，返回格式化响应"""
        instance = self.get_object()

        # 检查权限：只有管理员可以删除用户，且不能删除自己
        if not (request.user.is_admin or request.user.is_superuser):
            return Response({
                'success': False,
                'message': '权限不足，只有管理员可以删除用户'
            }, status=status.HTTP_403_FORBIDDEN)

        if instance.id == request.user.id:
            return Response({
                'success': False,
                'message': '不能删除自己的账户'
            }, status=status.HTTP_400_BAD_REQUEST)

        username = instance.username
        instance.delete()
        logger.info(f"✅ 管理员 {request.user.username} 删除用户成功: {username}")

        return Response({
            'success': True,
            'message': '用户删除成功'
        })


class UserManagementView(APIView):
    """用户管理视图 - 管理员功能"""
    permission_classes = [permissions.IsAuthenticated]

    def get_permissions(self):
        """只有管理员可以访问"""
        if self.request.method in ['POST', 'PUT', 'DELETE']:
            return [permissions.IsAuthenticated(), permissions.IsAdminUser()]
        return [permissions.IsAuthenticated()]

    def get(self, request):
        """获取用户列表"""
        if not (request.user.is_admin or request.user.is_superuser):
            return Response({
                'success': False,
                'message': '权限不足，只有管理员可以查看用户列表'
            }, status=status.HTTP_403_FORBIDDEN)

        users = User.objects.all().order_by('-created_at')
        serializer = UserManagementSerializer(users, many=True)

        # 统计信息
        stats = {
            'total_users': users.count(),
            'active_users': users.filter(is_active=True).count(),
            'admin_users': users.filter(is_admin=True).count(),
            'recent_users': users.filter(created_at__gte=datetime.now() - timedelta(days=7)).count()
        }

        return Response({
            'success': True,
            'data': serializer.data,
            'stats': stats
        })

    def post(self, request):
        """创建新用户"""
        if not (request.user.is_admin or request.user.is_superuser):
            return Response({
                'success': False,
                'message': '权限不足，只有管理员可以创建用户'
            }, status=status.HTTP_403_FORBIDDEN)

        logger.info(f"📝 管理员 {request.user.username} 创建用户，数据: {request.data}")

        # 处理创建用户的数据
        data = request.data.copy()

        # 如果没有提供密码，使用默认密码
        if 'password' not in data or not data['password']:
            data['password'] = 'default123'

        serializer = UserManagementSerializer(data=data)
        if serializer.is_valid():
            user = serializer.save()

            # 记录日志
            logger.info(
                f"✅ 管理员 {request.user.username} 成功创建用户: {user.username} (ID: {user.id})")

            return Response({
                'success': True,
                'message': '用户创建成功',
                'data': UserManagementSerializer(user).data
            }, status=status.HTTP_201_CREATED)

        logger.error(f"❌ 创建用户失败，验证错误: {serializer.errors}")
        return Response({
            'success': False,
            'message': '用户创建失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class UserManagementDetailView(APIView):
    """用户详情管理视图"""
    permission_classes = [permissions.IsAuthenticated]

    def get_permissions(self):
        """只有管理员可以访问"""
        return [permissions.IsAuthenticated(), permissions.IsAdminUser()]

    def get_object(self, pk):
        """获取用户对象"""
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            return None

    def get(self, request, pk):
        """获取单个用户详情"""
        user = self.get_object(pk)
        if not user:
            return Response({
                'success': False,
                'message': '用户不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 获取用户的项目统计
        from api.models import Project
        project_stats = Project.objects.filter(user=user).aggregate(
            total_projects=Count('id'),
            completed_projects=Count('id', filter=Q(status='completed')),
            processing_projects=Count('id', filter=Q(status='processing')),
            draft_projects=Count('id', filter=Q(status='draft'))
        )

        serializer = UserManagementSerializer(user)
        return Response({
            'success': True,
            'data': {
                **serializer.data,
                'project_stats': project_stats
            }
        })

    def put(self, request, pk):
        """更新用户信息"""
        user = self.get_object(pk)
        if not user:
            return Response({
                'success': False,
                'message': '用户不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        serializer = UserManagementSerializer(
            user, data=request.data, partial=True)
        if serializer.is_valid():
            user = serializer.save()
            logger.info(f"✅ 管理员 {request.user.username} 更新用户: {user.username}")

            return Response({
                'success': True,
                'message': '用户信息更新成功',
                'data': UserManagementSerializer(user).data
            })

        return Response({
            'success': False,
            'message': '更新失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        """删除用户"""
        user = self.get_object(pk)
        if not user:
            return Response({
                'success': False,
                'message': '用户不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 防止删除自己
        if user.id == request.user.id:
            return Response({
                'success': False,
                'message': '不能删除自己的账户'
            }, status=status.HTTP_400_BAD_REQUEST)

        username = user.username
        user.delete()

        logger.info(f"✅ 管理员 {request.user.username} 删除用户: {username}")

        return Response({
            'success': True,
            'message': f'用户 {username} 删除成功'
        })


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def user_stats(request):
    """用户统计信息"""
    user = request.user

    # 用户项目统计
    if user.is_admin or user.is_superuser:
        # 管理员可以看到所有统计
        project_stats = Project.objects.aggregate(
            total=Count('id'),
            completed=Count('id', filter=Q(status='completed')),
            processing=Count('id', filter=Q(status='processing')),
            draft=Count('id', filter=Q(status='draft'))
        )

        recent_projects = Project.objects.filter(
            created_at__gte=datetime.now() - timedelta(days=7)
        ).count()
    else:
        # 普通用户只能看到自己的统计
        project_stats = Project.objects.filter(user=user).aggregate(
            total=Count('id'),
            completed=Count('id', filter=Q(status='completed')),
            processing=Count('id', filter=Q(status='processing')),
            draft=Count('id', filter=Q(status='draft'))
        )

        recent_projects = Project.objects.filter(
            user=user,
            created_at__gte=datetime.now() - timedelta(days=7)
        ).count()

    return Response({
        'success': True,
        'data': {
            'project_stats': project_stats,
            'recent_projects': recent_projects,
            'user_info': {
                'username': user.username,
                'nickname': getattr(user, 'nickname', user.username),
                'join_date': user.date_joined,
                'last_login': user.last_login,
                'permissions': {
                    'is_admin': user.is_admin or user.is_superuser,
                    'is_superuser': user.is_superuser,
                    'can_manage_users': user.is_admin or user.is_superuser,
                    'can_access_api_debug': user.is_admin or user.is_superuser,
                    'can_view_all_projects': user.is_admin or user.is_superuser
                }
            }
        }
    })
